package com.example.multi.service.impl;

import cn.hutool.core.util.NumberUtil;

import com.example.multi.config.ExecutorConstant;

import com.example.multi.service.ITestAsyncService;

import lombok.extern.slf4j.Slf4j;
import org.springframework.scheduling.annotation.Async;
import org.springframework.scheduling.annotation.AsyncResult;
import org.springframework.stereotype.Service;

import java.util.concurrent.Future;

@Slf4j
@Service
public class TestAsyncService implements ITestAsyncService {

    /**
     * 异步方法，无返回值
     * @return
     */
    @Async
    @Override
    public void asyncFunction_1(){
        handleBusinessTime();
        log.info("asyncFunction_1 当前线程名称是：{}",Thread.currentThread().getName());
    };

    /////////////////异步方法，无返回值(指定线程池) start
    /**
     * 异步方法，无返回值(指定线程池)
     * @return
     */
    @Async(value = ExecutorConstant.simpleExecutor_2)
    @Override
    public void asyncFunction_2(){
        handleBusinessTime();
        log.info("asyncFunction_2 当前线程名称是：{}",Thread.currentThread().getName());
    };

    @Async(ExecutorConstant.simpleExecutor_2)
    @Override
    public void asyncFunction_3(){
        handleBusinessTime();
        log.info("asyncFunction_3 当前线程名称是：{}",Thread.currentThread().getName());

    };
    /////////////////异步方法，无返回值(指定线程池) end

    /**
     * 异步方法，有返回值
     * @return
     */
    @Async
    @Override
    public Future<Integer> asyncReturnDta_1(){
        handleBusinessTime();
        log.info("asyncReturnDta_1 当前线程名称是：{}",Thread.currentThread().getName());
        return new AsyncResult<Integer>(1);
    };
    /**
     * 异步方法，有返回值(指定线程池)
     * @return
     */
    @Async(ExecutorConstant.simpleExecutor_2)
    @Override
    public Future<Integer> asyncReturnDta_2(){
        handleBusinessTime();
        log.info("asyncReturnDta_2 当前线程名称是：{}",Thread.currentThread().getName());
        return new AsyncResult<Integer>(1);
    };


    /**
     * 异步方法，有返回值-超时
     * @return
     */
    @Async
    @Override
    public Future<Integer> asyncReturnDtaTimeOut(){
        handleBusinessTime();
        handleBusinessTime();
        handleBusinessTime();
        handleBusinessTime();
        log.info("asyncReturnDta_3 当前线程名称是：{}",Thread.currentThread().getName());
        return new AsyncResult<Integer>(1);
    };

    /**
     * 这方法 模拟处理业务或者 去操作数据库 消耗的时间
     */
    public static void handleBusinessTime(){
        //去数据库查询数据耗时 start
        int[] sleepTime = NumberUtil.generateRandomNumber(2000,5000,1);
        try {
            //Thread.sleep 休眠的时候 相当于 业务操作，或者请求数据库的需要消耗的时间
            Thread.sleep(sleepTime[0]);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        //去数据库查询数据耗时 end
    }
}
